from flask import g
from flask import request
from functools import wraps
from common import errors
import jwt
from config import Config
from app.user.model import User
from app.user.model import BlackList
from common.errors import PermissionDeniedDataAccessException


def token_required_func():
    authorization_header = request.headers.get('Authorization')
    if not authorization_header:
        raise errors.TokenMissedError
    if len(authorization_header.split(" ")) != 2:
        raise errors.TokenMissedError
    token = authorization_header.split(" ")[1]
    # 检查黑名单
    if BlackList.query.filter_by(token=str(token)).first():
        raise errors.AuthError("该令牌已加入黑名单，请重新登录")
    payload = jwt.decode(token, Config.SECRET_KEY)

    user_id = payload['sub']
    user = User.query.filter(User.id == user_id).first()
    if not user:
        raise errors.UserDoesNotExistError
    # set g
    g.user_id = user_id
    g.company_id = user.company_id
    g.token = token


# def check_token():
#     token_required_func()


def token_required(func):
    @wraps(func)
    def decorated(*args, **kwargs):
        # 解析token
        token_required_func()
        # authorization_header = request.headers.get('Authorization')
        # if not authorization_header:
        #     raise errors.TokenMissedError
        # if len(authorization_header.split(" ")) != 2:
        #     raise errors.TokenMissedError
        # token = authorization_header.split(" ")[1]
        # # 检查黑名单
        # if BlackList.query.filter_by(token=str(token)).first():
        #     raise errors.AuthError("该令牌已加入黑名单，请重新登录")
        # payload = jwt.decode(token, Config.SECRET_KEY)
        #
        # user_id = payload['sub']
        # user = User.query.filter(User.id == user_id).first()
        # if not user:
        #     raise errors.UserDoesNotExistError
        # # set g
        # g.user_id = user_id
        # g.company_id = user.company_id
        # g.token = token
        return func(*args, **kwargs)

    return decorated






def permission_can(current_user, permission):
    """
    检测用户是否有特定权限
    :param current_user
    :param permission
    :return:
    """
    roles = current_user.roles
    # roles 中有一个有 permissions
    for role in roles:
        if permission in role.permissions:
            return True
    return False


def permission_required(permission):
    """
    权限认证装饰器
    :param permission:
    :return:
    """

    def decorator(f):
        @wraps(f)
        def decorated_function(*args, **kwargs):
            current_user = User.query.filter_by(id=g.user_id).first()
            if permission_can(current_user, permission):
                return f(*args, **kwargs)
            else:
                raise PermissionDeniedDataAccessException

        return decorated_function

    return decorator


def check_permission(permission):
    current_user = User.query.filter_by(id=g.user_id).first()
    if not permission_can(current_user, permission):
        raise PermissionDeniedDataAccessException


def is_permission_can(permission):
    current_user = User.query.filter_by(id=g.user_id).first()
    return permission_can(current_user, permission)